package com.taysear.bus;

import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import com.taysear.bus.util.Constants;
import com.taysear.bus.util.Results;
import com.taysear.bus.util.Util;
import com.taysear.dbservice.DbServicesPrx;
import com.taysear.dbservice.ServiceParameter;
import com.taysear.dbservice.ServiceResult;
import com.taysear.domain.Booking;
import com.taysear.domain.BusFare;
import com.taysear.domain.Route;
import com.taysear.domain.helper.Temp;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.BeanContainer;
import com.vaadin.data.util.BeanItem;
import com.vaadin.ui.Button;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.CustomLayout;
import com.vaadin.ui.Form;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.OptionGroup;
import com.vaadin.ui.Panel;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Table.ColumnGenerator;
import com.vaadin.ui.themes.Runo;

@SuppressWarnings("serial")
public class ManageBooking extends HorizontalLayout {
	HorizontalLayout actionButtons = new HorizontalLayout();
	Table bookingTable = new Table();
	Form manageBookingForm = null;
	
	Button changeBookingButton = null;
	Button makeBookingOpenButton = null;
	Button cancelBookingButton = null;
	Button viewBookingButton = null;
	
	Integer startIndex = 1;
	Boolean isSaved = false;

	public ManageBooking() {
		CustomLayout manageBookingLayout = new CustomLayout("manageBooking");
		
		actionButtons = new HorizontalLayout();
		actionButtons.setVisible(false);
		actionButtons.setSpacing(true);
		
		changeBookingButton = getChangeBookingButton();
		makeBookingOpenButton = getMakeBookingOpenButton();
		cancelBookingButton = getCancelBookingButton();
		viewBookingButton = getViewBookingButton();
		
		//actionButtons.addComponent(viewBookingButton);
		actionButtons.addComponent(changeBookingButton);
		actionButtons.addComponent(makeBookingOpenButton);
		actionButtons.addComponent(cancelBookingButton);
		
		bookingTable = getTable();
		manageBookingForm = getManageBookingForm();
		
		manageBookingLayout.addComponent(manageBookingForm, "form");
		manageBookingLayout.addComponent(bookingTable, "result");
		
		manageBookingLayout.addComponent(actionButtons, "actionButtons");
		
		addComponent(manageBookingLayout);
	}
	
	/**
	 * Gets a form that is used to search bookings in the system.
	 * 
	 * @return Form
	 */
	private Form getManageBookingForm() {
		manageBookingForm = new Form();
		manageBookingForm.setCaption("Manage booking");
		
		NativeSelect filterBy = new NativeSelect("Filter by");
		filterBy.setImmediate(true);
		filterBy.setNullSelectionAllowed(false);
		BeanContainer<Integer, Temp> container = new BeanContainer<Integer, Temp>(Temp.class);
		container.setBeanIdProperty("id");
		
		container.addItem(1, new Temp(1, "Booking id"));
		container.addItem(2, new Temp(2, "Mobile"));
		
		filterBy.setContainerDataSource(container);
		filterBy.setValue(container.getItemIds().iterator().next());
		filterBy.setItemCaptionPropertyId("description");
		manageBookingForm.addField("filterBy", filterBy);
		
		final TextField filterValue = new TextField("Filter value");
		filterValue.focus();
		filterValue.setRequired(true);
		filterValue.setRequiredError("This field is required.");
		filterValue.setImmediate(true);
		manageBookingForm.addField("filterValue", filterValue);
		
		filterBy.addListener(new ValueChangeListener() {
			@Override
			public void valueChange(ValueChangeEvent event) {
				if("2".equals(event.getProperty().getValue().toString())) {
					filterValue.setValue(AppData.getUser().getEmployee().getStation().getCountry().getCountryTelCode());
				} else {
					filterValue.setValue("");
				}
			}
		});
		
		Button searchButton = getSearchButton();
		manageBookingForm.addField("", searchButton);
		return manageBookingForm;
	}
	
	/**
	 * Gets a button to search bookings.
	 * 
	 * @param manageBookingForm
	 * 
	 * @return Button
	 */
	private Button getSearchButton() {
		Button button = new Button("Search");
		button.addStyleName("blueButton");
		button.setDisableOnClick(true);
		button.addListener(new Button.ClickListener() {
		    @Override
		    public void buttonClick(ClickEvent event) {
		    	BusApplication app = (BusApplication) getApplication();
		    	searchBooking(app);
		    	event.getButton().setEnabled(true);
		    }
		});
		
		return button;
	}
	
	/**
	 * Search bookings.
	 * 
	 * @param app
	 */
	private void searchBooking(BusApplication app) {
		if(manageBookingForm.isValid()) {
    		startIndex = 1;
    		isSaved = false;
    		
    		ServiceParameter sp = new ServiceParameter(new HashMap<String, String>());
    		sp.param.put("filterBy", manageBookingForm.getField("filterBy").getValue().toString());
    		sp.param.put("filterValue", manageBookingForm.getField("filterValue").getValue().toString());
    		sp.param.put("startIndex", startIndex.toString());
    		sp.param.put("pageSize", Constants.PAGE_SIZE.toString());
    		
    		DbServicesPrx dbServicesPrx = app.getDbServiceProxy();
    		ServiceResult sr = dbServicesPrx.searchBooking(sp);
    		
    		BeanContainer<Integer, Booking> container = new BeanContainer<Integer, Booking>(Booking.class);
    		container.setBeanIdProperty("bookingId");
    		
    		if(sr.status) {
    			if(sr.param.get("RECORDS") != null) {
	    			Results r = Util.getObjectsFromXmlResult(sr.param.get("RECORDS"), Booking.class);
					for (Object object : r.getRows()) {
						Booking booking = (Booking) object;
						container.addItem(booking.getBookingId(), booking);
					}
					bookingTable.setVisible(true);
					actionButtons.setVisible(true);
					bookingTable.setContainerDataSource(container);
					
					String[] columnsCollectParcelForm = {"Id", "Date", "From", "To", "Name", "Mobile", "Seat", "Status" };	
					bookingTable.setVisibleColumns(columnsCollectParcelForm);
    			} else {
    				bookingTable.setVisible(false);
	    			actionButtons.setVisible(false);
					bookingTable.setContainerDataSource(null);
					app.showNotification(Constants.MN_NO_RESULT);
    			}
    		} else {
    			app.showErrorNotification(sr.message);
    			bookingTable.setVisible(false);
    			actionButtons.setVisible(false);
				bookingTable.setContainerDataSource(null);
    		}
    	} else {
    		app.showErrorNotification(Constants.ME_FORM_FIELDS_REQUIRED);
    	}
	}
	
	/**
	 * Gets a button to change a booking.
	 * 
	 * @return Button
	 */
	private Button getChangeBookingButton() {
		Button button = new Button("Change");
		button.addStyleName("greenButton");
		button.setEnabled(false);
		button.setDisableOnClick(true);
		button.addListener(new Button.ClickListener() {
		    @Override
		    public void buttonClick(ClickEvent event) {
		    	final Booking booking = ((BeanItem<Booking>) bookingTable.getItem(bookingTable.getValue())).getBean();
		    	
		    	Window window = new Window("Change booking");
				
		    	String panelCaption = "You have selected to change the booking: <b>"+ booking.getBookingId() +"</b> for <b>"+ booking.getCustomerName() +"</b>.";
		    	Panel panel = new Panel(panelCaption);
		    	panel.addStyleName(Runo.PANEL_LIGHT);
		    	
		    	Button close = getCloseButton(window);
		    	
		    	final CreateBooking createBooking = new CreateBooking("Change booking", booking);
		    	
		    	createBooking.bookingType.setValue(booking.getIsOneWay() ? 1 : 2);
		    	createBooking.bookingType.setReadOnly(true);
		    	
		    	createBooking.customerName.setValue(booking.getCustomerName());
		    	createBooking.customerName.setReadOnly(true);
		    	
		    	createBooking.customerMobile.setValue(booking.getCustomerMobile());
		    	createBooking.customerMobile.setReadOnly(true);
		    	
		    	createBooking.nationality.setValue(booking.getNationality());
		    	createBooking.nationality.setReadOnly(true);
		    	
		    	createBooking.idNumber.setValue(booking.getIdNumber());
		    	createBooking.idNumber.setReadOnly(true);
		    	
		    	createBooking.pickupPoint.setValue(booking.getPickupPoint());
		    	
		    	createBooking.childAge.setValue(booking.getChildAge());
		    	createBooking.childAge.setReadOnly(true);
		    	
		    	Form form = createBooking.form;
		    	
		    	HorizontalLayout footer = (HorizontalLayout) form.getFooter();
				footer.addStyleName("formFooter");
				footer.setSpacing(true);

				Button print = createBooking.getPrintButton(form);
				Button change = getSaveChangeBookingButton(createBooking, form, booking, print) ;
				
				footer.addComponent(change);
				footer.addComponent(print);
				footer.addComponent(close);
		    	
		    	panel.addComponent(form);
		    	
				window.center();
            	window.setModal(true);
        		VerticalLayout verticalLayout = (VerticalLayout) window.getContent();
        		verticalLayout.setMargin(true);
                verticalLayout.setSpacing(true);
        		verticalLayout.setSizeUndefined();
        		verticalLayout.addComponent(panel);
            	getApplication().getMainWindow().addWindow(window);
		    	
		    	event.getButton().setEnabled(true);
		    }
		});
		return button;
	}
	
	/**
	 * Gets a button changeto make a booking open.
	 * 
	 * @param createBooking
	 * @param form
	 * @param booking
	 * @param print
	 * 
	 * @return Button
	 */
	private Button getSaveChangeBookingButton(final CreateBooking createBooking, final Form form, final Booking booking, final Button print) {
		Button button = new Button("Change");
		button.addStyleName("blueButton");
		button.setDisableOnClick(true);
		button.addListener(new Button.ClickListener() {
		    @Override
		    public void buttonClick(ClickEvent event) {
		    	BusApplication app = (BusApplication) getApplication();
		    	if(form.isValid()) {
		    		Temp type = ((BeanItem<Temp>)((OptionGroup)form.getField("bookingType")).getContainerDataSource().getItem(form.getField("bookingType").getValue())).getBean();
		    		Route route = ((BeanItem<Route>)((ComboBox)form.getField("route")).getContainerDataSource().getItem(form.getField("route").getValue())).getBean();
		    		BusFare busFare = ((BeanItem<BusFare>)((ComboBox)form.getField("amount")).getContainerDataSource().getItem(form.getField("amount").getValue())).getBean();
		    		
		    		List<String> departureTime = Arrays.asList(route.getDepartureTime().split(":"));
		    		List<String> reportingTime = Arrays.asList(route.getReportingTime().split(":"));
		    		
		    		Date travelDate = Util.setDateHourAndMinute((Date) form.getField("travelDate").getValue(), Integer.parseInt(departureTime.get(0)), Integer.parseInt(departureTime.get(1)), "pm".equalsIgnoreCase(route.getAmpm()));
		    		Date reportingDate = Util.setDateHourAndMinute((Date) form.getField("travelDate").getValue(), Integer.parseInt(reportingTime.get(0)), Integer.parseInt(reportingTime.get(1)), "pm".equalsIgnoreCase(route.getAmpm()));
		    		
		    		ServiceParameter sp = new ServiceParameter(new HashMap<String, String>());
		    		sp.param.put("userId", AppData.getUser().getUserId().toString());
		    		sp.param.put("bookingId", booking.getBookingId().toString());
		    		sp.param.put("travelDate", Util.formatDateForDB(travelDate));
		    		sp.param.put("reportingDate", Util.formatDateForDB(reportingDate));
		    		sp.param.put("loadingsheetId", route.getLoadingsheetId().toString());
		    		sp.param.put("seatId", form.getField("seat").getValue().toString());
		    		sp.param.put("oldSeatId", booking.getRouteTimeSeat().toString());
		    		sp.param.put("name", form.getField("name").getValue().toString());
		    		sp.param.put("mobile", form.getField("mobile").getValue().toString());
		    		sp.param.put("nationality", form.getField("nationality").getValue().toString());
		    		sp.param.put("idNumber", form.getField("idNumber").getValue().toString());
		    		sp.param.put("childAge", form.getField("childAge").getValue().toString());
		    		sp.param.put("fromSubstation", form.getField("fromSubstation").getValue().toString());
		    		sp.param.put("toSubstation", form.getField("toSubstation").getValue().toString());
		    		sp.param.put("amount", busFare.getAmount().toString());
		    		sp.param.put("currencyName", busFare.getCurrencyName());
		    		sp.param.put("pickupPoint", form.getField("pickupPoint").getValue().toString());
		    		sp.param.put("bookingAction", ""+Constants.BOOKING_ACTION_CHANGE);
		    		sp.param.put("bookingStatus", ""+Constants.BOOKING_STATUS_CHANGED);
		    		sp.param.put("seatStatus", ""+Constants.SEAT_STATUS_UNAVAILABLE);
		    		sp.param.put("oldSeatStatus", ""+Constants.SEAT_STATUS_AVAILABLE);
		    		sp.param.put("isOneWay", (type.getId() == Constants.BOOKING_TYPE_ONE_WAY ? "1" : "0"));
		    		
		    		DbServicesPrx dbServicesPrx = app.getDbServiceProxy();
		    		ServiceResult sr = dbServicesPrx.changeBooking(sp);
		    		
		    		if(sr.status) {
		    			form.setReadOnly(true);
		    			app.showNotification("Booking is changed.");
		    			isSaved = true;
		    			
		    			createBooking.bookingId = sr.param.get("bookingId");
		    			createBooking.actionDate = Util.formatDate(sr.param.get("actionDate"));
		    			print.setEnabled(true);
		    		} else {
		    			app.showErrorNotification(sr.message);
		    			event.getButton().setEnabled(true);
		    		}
		    	} else {
		    		app.showErrorNotification(Constants.ME_FORM_FIELDS_REQUIRED);
		    		event.getButton().setEnabled(true);
		    	}
		    }
		});
		
		return button;
	}
	
	/**
	 * Gets a button to make a booking open.
	 * 
	 * @return Button
	 */
	private Button getMakeBookingOpenButton() {
		Button button = new Button("Open");
		button.addStyleName("greenButton");
		button.setEnabled(false);
		button.setDisableOnClick(true);
		button.addListener(new Button.ClickListener() {
		    @Override
		    public void buttonClick(ClickEvent event) {
		    	Booking booking = ((BeanItem<Booking>) bookingTable.getItem(bookingTable.getValue())).getBean();
		    	
		    	Window window = new Window("Open booking");
				
		    	String panelCaption = "You have selected to make the booking: <b>"+ booking.getBookingId() +"</b> for <b>"+ booking.getCustomerName() +"</b> an open booking.";
		    	Panel panel = new Panel(panelCaption);
		    	panel.addStyleName(Runo.PANEL_LIGHT);
		    	
		    	Form form = new Form();
		    	
		    	TextArea description = new TextArea("description");
		    	description.setWidth("200px");
		    	description.setRequired(true);
		    	description.setRequiredError("This field is required");
		    	form.addField("description", description);

		    	Button saveOpenBookingButton = getSaveOpenBookingButton(form, booking);
		    	Button close = getCloseButton(window);
		    	
		    	HorizontalLayout buttons = new HorizontalLayout();
		    	buttons.setSpacing(true);
		    	buttons.addComponent(saveOpenBookingButton);
		    	buttons.addComponent(close);
		    	form.getLayout().addComponent(buttons);
		    	
		    	panel.addComponent(form);
		    	
				window.center();
            	window.setModal(true);
        		VerticalLayout verticalLayout = (VerticalLayout) window.getContent();
        		verticalLayout.setMargin(true);
                verticalLayout.setSpacing(true);
        		verticalLayout.setSizeUndefined();
        		verticalLayout.addComponent(panel);
            	getApplication().getMainWindow().addWindow(window);
		    	
		    	event.getButton().setEnabled(true);
		    }
		});
		return button;
	}
	
	/**
	 * Gets a button to close the window that is passed as a parameter.
	 * 
	 * @param window
	 * @return Button
	 */
	public Button getCloseButton(final Window window) {
		Button button = new Button("Close");
		button.addStyleName("grayButton");
		button.addListener(new Button.ClickListener() {
			public void buttonClick(ClickEvent event) {
				window.getParent().removeWindow(window);
				BusApplication app = (BusApplication) getApplication();
				if(isSaved)
					searchBooking(app);
			}
    	});
    	return button;
	}
	
	/**
	 * Gets a button to set booking to open. 
	 * 
	 * @param form
	 * @param booking
	 * @return Button
	 */
	private Button getSaveOpenBookingButton(final Form form, final Booking booking) {
		Button button = new Button("Save");
		button.addStyleName("blueButton");
		button.setDisableOnClick(true);
		button.addListener(new Button.ClickListener() {
		    @Override
		    public void buttonClick(ClickEvent event) {
		    	BusApplication app = (BusApplication) getApplication();
		    	if(form.isValid()) {
		    		ServiceParameter sp = new ServiceParameter(new HashMap<String, String>());
		    		sp.param.put("userId", AppData.getUser().getUserId().toString());
		    		sp.param.put("bookingId", booking.getBookingId().toString());
		    		sp.param.put("amount", booking.getAmount().toString());
		    		sp.param.put("routeTimeSeatId", booking.getRouteTimeSeat().toString());
		    		sp.param.put("description", form.getField("description").getValue().toString());
		    		sp.param.put("bookingAction", ""+Constants.BOOKING_ACTION_OPEN);
		    		sp.param.put("bookingStatus", ""+Constants.BOOKING_STATUS_OPEN);
		    		sp.param.put("seatStatus", ""+Constants.SEAT_STATUS_AVAILABLE);
		    		sp.param.put("currencyId", AppData.getUser().getEmployee().getStation().getCountry().getCurrency().getCurrencyId().toString());
		    		
		    		DbServicesPrx dbServicesPrx = app.getDbServiceProxy();
		    		ServiceResult sr = dbServicesPrx.setBookingOpen(sp);
		    		
		    		if(sr.status) {
		    			isSaved = true;
		    			app.showNotification("Booking is set to open.");
		    		} else {
		    			app.showErrorNotification(sr.message);
		    			event.getButton().setEnabled(true);
		    		}
		    	} else {
		    		event.getButton().setEnabled(true);
		    		app.showErrorNotification(Constants.ME_FORM_FIELDS_REQUIRED);
		    	}
		    }
		});
		return button;
	}
	
	/**
	 * Gets a button to cancel a booking.
	 * 
	 * @return Button
	 */
	private Button getCancelBookingButton() {
		Button button = new Button("Cancel");
		button.addStyleName("redButton");
		button.setEnabled(false);
		button.setDisableOnClick(true);
		button.addListener(new Button.ClickListener() {
		    @Override
		    public void buttonClick(ClickEvent event) {
		    	Booking booking = ((BeanItem<Booking>) bookingTable.getItem(bookingTable.getValue())).getBean();
		    	
		    	Window window = new Window("Cancel booking");
				
		    	String panelCaption = "You have selected to cancel booking: <b>"+ booking.getBookingId() +"</b> for <b>"+ booking.getCustomerName() +"</b>.";
		    	Panel panel = new Panel(panelCaption);
		    	panel.addStyleName(Runo.PANEL_LIGHT);
		    	
		    	Form form = new Form();
		    	
		    	TextArea description = new TextArea("description");
		    	description.setWidth("200px");
		    	description.setRequired(true);
		    	description.setRequiredError("This field is required");
		    	form.addField("description", description);

		    	Button saveOpenBookingButton = getSaveCancelBookingButton(form, booking);
		    	Button close = getCloseButton(window);
		    	
		    	HorizontalLayout buttons = new HorizontalLayout();
		    	buttons.setSpacing(true);
		    	buttons.addComponent(saveOpenBookingButton);
		    	buttons.addComponent(close);
		    	form.getLayout().addComponent(buttons);
		    	
		    	panel.addComponent(form);
		    	
				window.center();
            	window.setModal(true);
        		VerticalLayout verticalLayout = (VerticalLayout) window.getContent();
        		verticalLayout.setMargin(true);
                verticalLayout.setSpacing(true);
        		verticalLayout.setSizeUndefined();
        		verticalLayout.addComponent(panel);
            	getApplication().getMainWindow().addWindow(window);
		    	event.getButton().setEnabled(true);
		    }
		});
		return button;
	}
	
	/**
	 * Gets a button to cancel booking. 
	 * 
	 * @param form
	 * @param booking
	 * @return Button
	 */
	private Button getSaveCancelBookingButton(final Form form, final Booking booking) {
		Button button = new Button("Save");
		button.addStyleName("blueButton");
		button.setDisableOnClick(true);
		button.addListener(new Button.ClickListener() {
		    @Override
		    public void buttonClick(ClickEvent event) {
		    	BusApplication app = (BusApplication) getApplication();
		    	if(form.isValid()) {
		    		ServiceParameter sp = new ServiceParameter(new HashMap<String, String>());
		    		sp.param.put("userId", AppData.getUser().getUserId().toString());
		    		sp.param.put("bookingId", booking.getBookingId().toString());
		    		sp.param.put("routeTimeSeatId", booking.getRouteTimeSeat().toString());
		    		sp.param.put("description", form.getField("description").getValue().toString());
		    		sp.param.put("bookingAction", ""+Constants.BOOKING_ACTION_CANCEL);
		    		sp.param.put("bookingStatus", ""+Constants.BOOKING_STATUS_CANCELLED);
		    		sp.param.put("seatStatus", ""+Constants.SEAT_STATUS_AVAILABLE);
		    		
		    		DbServicesPrx dbServicesPrx = app.getDbServiceProxy();
		    		ServiceResult sr = dbServicesPrx.cancelBooking(sp);
		    		
		    		if(sr.status) {
		    			isSaved = true;
		    			app.showNotification("Booking is cancelled.");
		    		} else {
		    			app.showErrorNotification(sr.message);
		    			event.getButton().setEnabled(true);
		    		}
		    	} else {
		    		event.getButton().setEnabled(true);
		    		app.showErrorNotification(Constants.ME_FORM_FIELDS_REQUIRED);
		    	}
		    }
		});
		return button;
	}
	
	/**
	 * Gets a button to view a booking.
	 * 
	 * @return Button
	 */
	private Button getViewBookingButton() {
		Button button = new Button("View");
		button.addStyleName("grayButton");
		button.setEnabled(false);
		button.setDisableOnClick(true);
		button.addListener(new Button.ClickListener() {
		    @Override
		    public void buttonClick(ClickEvent event) {
		    	Window window = new Window("View booking");
		    	
		    	Form form = new Form();
		    	form.setWidth("500px");
		    	form.setItemDataSource(bookingTable.getItem(bookingTable.getValue()));
		    	
		    	String [] columns = new String[] {"bookingId", "travelDate", "seatDescription", "dateCreated", "statusDescription", "customerName", "customerMobile", "idNumber", "childAge", "fromSubstationDescription", "toSubstationDescription", "amount", "currencyName", "pickupPoint"};
				form.setVisibleItemProperties(columns);
				
				Button close = Util.getCloseButton(window);
		    	
				window.center();
            	window.setModal(true);
        		VerticalLayout verticalLayout = (VerticalLayout) window.getContent();
        		verticalLayout.setMargin(true);
                verticalLayout.setSpacing(true);
        		verticalLayout.setSizeUndefined();
        		verticalLayout.addComponent(form);
        		verticalLayout.addComponent(close);
            	getApplication().getMainWindow().addWindow(window);
		    	
		    	event.getButton().setEnabled(true);
		    }
		});
		return button;
	}
	
	/**
	 * Gets a table that is used to display the result.
	 * 
	 * @return Table
	 */
	private Table getTable() {
		bookingTable.setVisible(false);
		bookingTable.addStyleName(Runo.TABLE_SMALL);
		bookingTable.setSelectable(true);
		bookingTable.setImmediate(true);
		bookingTable.addListener(new ValueChangeListener() {
			@Override
			public void valueChange(ValueChangeEvent event) {
				if(event.getProperty().getValue() != null) {
					Booking booking = ((BeanItem<Booking>) bookingTable.getItem(bookingTable.getValue())).getBean();
					Date now = new Date();
					Date date = Util.getDate(booking.getReportingDate());
					
					Boolean openBookingAllowed = now.compareTo(date) == 0 | now.compareTo(date) == -1;
					
					if(booking.getStatus().intValue() == Constants.BOOKING_STATUS_ACTIVE && openBookingAllowed) { // active booking, can be cancelled or set to open.
						changeBookingButton.setEnabled(true);
						makeBookingOpenButton.setEnabled(true);
						cancelBookingButton.setEnabled(true);
					} else if(booking.getStatus().intValue() == Constants.BOOKING_STATUS_OPEN) { // open booking, can be cancelled.
						changeBookingButton.setEnabled(true);
						cancelBookingButton.setEnabled(false);
						makeBookingOpenButton.setEnabled(false);
					} else if(booking.getStatus().intValue() == Constants.BOOKING_STATUS_RESERVATION) { // booking is a reservation, can be cancelled.
						changeBookingButton.setEnabled(true);
						cancelBookingButton.setEnabled(true);
						makeBookingOpenButton.setEnabled(false);
					} else {
						changeBookingButton.setEnabled(false);
						makeBookingOpenButton.setEnabled(false);
						cancelBookingButton.setEnabled(false);
					}
					viewBookingButton.setEnabled(true); // view booking is allowed in any case
				} else {
					viewBookingButton.setEnabled(false);
					changeBookingButton.setEnabled(false);
					makeBookingOpenButton.setEnabled(false);
					cancelBookingButton.setEnabled(false);
				}
			}
		});
		bookingTable.addGeneratedColumn("Id", new ColumnGenerator() {
			  public Component generateCell(Table source, Object itemId,
			            Object columnId) {
			      if (bookingTable.getItem(itemId).getItemProperty("bookingId").getValue() != null) {
			          Label l = new Label();
			          l.setValue(bookingTable.getItem(itemId).getItemProperty("bookingId").getValue());
			          l.setWidth("50px");
			          return l;
			      }
			      return null;
			  }
			});
		bookingTable.addGeneratedColumn("Date", new ColumnGenerator() {
			  public Component generateCell(Table source, Object itemId,
			            Object columnId) {
			      if (bookingTable.getItem(itemId).getItemProperty("travelDate").getValue() != null) {
			          Label l = new Label();
			          l.setValue(Util.formatDate(bookingTable.getItem(itemId).getItemProperty("travelDate").getValue().toString()));
			          l.setWidth("100px");
			          return l;
			      }
			      return null;
			  }
			});
		bookingTable.addGeneratedColumn("From", new ColumnGenerator() {
			  public Component generateCell(Table source, Object itemId,
			            Object columnId) {
			      if (bookingTable.getItem(itemId).getItemProperty("fromSubstationDescription").getValue() != null) {
			          Label l = new Label();
			          l.setValue(bookingTable.getItem(itemId).getItemProperty("fromSubstationDescription").getValue());
			          l.setWidth("150px");
			          return l;
			      }
			      return null;
			  }
			});
		bookingTable.addGeneratedColumn("To", new ColumnGenerator() {
			  public Component generateCell(Table source, Object itemId,
			            Object columnId) {
			      if (bookingTable.getItem(itemId).getItemProperty("toSubstationDescription").getValue() != null) {
			          Label l = new Label();
			          l.setValue(bookingTable.getItem(itemId).getItemProperty("toSubstationDescription").getValue());
			          l.setWidth("150px");
			          return l;
			      }
			      return null;
			  }
			});
		bookingTable.addGeneratedColumn("Name", new ColumnGenerator() {
			  public Component generateCell(Table source, Object itemId,
			            Object columnId) {
			      if (bookingTable.getItem(itemId).getItemProperty("customerName").getValue() != null) {
			          Label l = new Label();
			          l.setValue(bookingTable.getItem(itemId).getItemProperty("customerName").getValue());
			          l.setWidth("180px");
			          return l;
			      }
			      return null;
			  }
			});
		bookingTable.addGeneratedColumn("Mobile", new ColumnGenerator() {
			  public Component generateCell(Table source, Object itemId,
			            Object columnId) {
			      if (bookingTable.getItem(itemId).getItemProperty("customerMobile").getValue() != null) {
			          Label l = new Label();
			          l.setValue(bookingTable.getItem(itemId).getItemProperty("customerMobile").getValue());
			          l.setWidth("100px");
			          return l;
			      }
			      return null;
			  }
			});
		bookingTable.addGeneratedColumn("Seat", new ColumnGenerator() {
			  public Component generateCell(Table source, Object itemId,
			            Object columnId) {
			      if (bookingTable.getItem(itemId).getItemProperty("seatDescription").getValue() != null) {
			          Label l = new Label();
			          l.setValue(bookingTable.getItem(itemId).getItemProperty("seatDescription").getValue());
			          l.setWidth("70px");
			          return l;
			      }
			      return null;
			  }
			});
		bookingTable.addGeneratedColumn("Status", new ColumnGenerator() {
			  public Component generateCell(Table source, Object itemId,
			            Object columnId) {
			      if (bookingTable.getItem(itemId).getItemProperty("statusDescription").getValue() != null) {
			          Label l = new Label();
			          l.setValue(bookingTable.getItem(itemId).getItemProperty("statusDescription").getValue());
			          l.setWidth("70px");
			          return l;
			      }
			      return null;
			  }
			});
		
		return bookingTable;
	}
}
